<script setup lang="ts">
    import { ref, inject, computed, type Ref } from 'vue';
    import { useUserStore} from '@/stores/user';
    import { useChatStore} from '@/stores/chat';
    import type { MessageItem, MessageType } from '@/services/type';

    import RenderMessage from '@/components/ChatBox/Content/Render/index.vue';
    import ContextMenu from '@/components/ChatBox/Content/ContextMenu/index.vue';
    import { api } from '@/services/api';

    // 属性
    const { item } = defineProps<{item: MessageItem}>();

    const userStore = useUserStore();
    const chatStore = useChatStore();

    // 菜单Ref
    const contextMenu = ref<InstanceType<typeof ContextMenu>>();
    // 右击菜单参数
    const menuOptions = ref({
        x: 0,
        y: 0
    });
    // 是否显示右击菜单
    const isShowMenu = ref(false);
    // 是否回复
    const isReply = computed(() => userStore.userInfo.yhnm == item.fromUser.yhnm);
    const messageItemRef = inject<Ref>('messageItemRef')
    const scrollToOffset = inject<any>('scrollToOffset')

    // 右击
    const openMenu = (e: MouseEvent) => {
        const { x, y } = e;
        // 这个应该是相对于整个浏览器页面的x坐标，左上角为坐标原点（0,0）
        menuOptions.value.x = x;
        // 这个应该是相对于整个浏览器页面的y坐标，左上角为坐标原点（0,0）
        menuOptions.value.y = y;
        // 显示菜单
        isShowMenu.value = true; 
        // 获取焦点事件
        contextMenu.value?.handleFocus();
    }

    // 滚动到消息
    const scrollToMsg = async (msg: MessageType) => {
        const { id } = msg
        const { reply } = msg.body
        // 不允许跳转不跳转，目前是 100 条(后端配置)以内允许跳转
        if (!reply || !reply.canCallback) return
        // 如果消息已经加载过了，就直接跳转
        const index = chatStore.getMsgIndex(reply.id)
        if (index > -1) {
            console.log(getOffsetTop(reply.id) as number);
            scrollToOffset(getOffsetTop(reply.id) as number - 60, true)
        } else {
            // 如果没有加载过，就先加载，然后跳转
            const curMsgIndex = chatStore.getMsgIndex(id)
            // +1 是在 reply.gapCount - curMsgIndex 刚好是 pageSize 倍数的时候，跳转到的是第一条消息，会触发加载更多，样式会乱掉
            const needLoadPageSize = Math.ceil((reply.gapCount - curMsgIndex + 1) / 20) * 20
            // 加载数据
            await chatStore.getMessageList(msg.sessionId, needLoadPageSize)
            // 跳转
            // FIXME 这时候新加载消息了，所以会有滚动冲突，故不加动画效果，否则会很怪异。
            setTimeout(() => scrollToOffset(getOffsetTop(reply.id) as number - 60, true), 0);
            // TODO 跳转到的消息 高亮一下
        }
    }

    //
    const getOffsetTop = (toId: number): any => {
        let offsetTop: number = 0
        Array.from(messageItemRef?.value.children).forEach(async (data: any) => {
            const id: number = data.getAttribute("id");
            if(id == toId) {
                offsetTop = data.offsetTop;
            }
        });
        return offsetTop;
    }

    /**
     * 删除消息
     * @param msgId 
     * @param mailbox 
     */
    const deleteMessage = (msgId: number, mailbox: number) => {
        // 删除消息
        api
        .chat
        .deleteMessage({ msgId, mailbox })
        .then(response => {
            if(response.code == 0) {
                const index: number = chatStore.chatMessageList.findIndex(item => item.message.id == msgId);
                if(index !== -1) {
                    chatStore.chatMessageList.splice(index, 1);
                    isShowMenu.value = false;
                }
            }
        });
    }

</script>
<template>
    <div 
        ref="items"
        class="message-item" 
        :class="{ 'left' : !isReply, 'right' : isReply }"
    >
        <div class="message-time" v-if="item.timeBlock">
            {{ item.timeBlock }}
        </div>
        <div class="message-tips" v-if="item.message.type == 8">
            {{ item.message.body }}
        </div>
        <div class="message-body" v-if="item.message.type != 8">
            <div class="message-avatar">
                <img :src="item.fromUser.avatar" />
            </div>
            <div class="message-content" @contextmenu.prevent="openMenu($event)">
                <!-- 渲染消息内容体 -->
                <render-message :message="item.message" />
                <!-- 消息回复部分 -->
                <div 
                    v-if="item.message.body?.reply" 
                    class="message-reply" 
                    :class="{ pointer: item.message.body.reply.canCallback }" 
                    @click="scrollToMsg(item.message)"
                >
                    <el-icon v-if="item.message.body.reply.canCallback" :size="12"><Upload /></el-icon>
                    <span class="ellipsis" style="margin-left: 2px;">
                        {{ item.message.body.reply.nickName }}：{{ item.message.body.reply.body }}
                    </span>
                </div>
            </div>
            <!-- 消息右键菜单 -->
            <context-menu 
                ref="contextMenu"
                :visible="isShowMenu" 
                :options="menuOptions" 
                :message="item.message" 
                @delete="deleteMessage(item.message.id, (isReply ? 0 : 1))"
                @hide="isShowMenu = false"
            />
        </div>
    </div>
</template>
<style lang="less" scoped>
    .message-item {
        margin: 10px;
        & .message-time, .message-tips {
            padding-top: 10px;
            padding-bottom: 10px;
            font-size: 12px;
            text-align: center;
            color: #999;
            line-height: 10px;
            -webkit-box-sizing: content-box;
            box-sizing: content-box;
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }
        & .message-body {
            & .message-avatar {
                display: inline-block;
                width: 28px;
                height: 28px;
                vertical-align: top;
                & img {
                    display: block;
                    width: 28px;
                    height: 28px;
                    border-radius: 50%;
                    overflow: hidden;
                }
            }
            & .message-content {
                position: relative;
                display: inline-block;
                max-width: 400px;
                min-height: 35px;
                margin-right: 14px;
                margin-left: 14px;
                font-size: 14px;
                line-height: 20px;
                color: white;
                vertical-align: middle;
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
                white-space: pre-wrap;
                word-break: break-all;
                letter-spacing: .1px;
                text-align: left;
            }
            & .message-reply {
                display: flex;
                align-items: center;
                width: fit-content;
                padding: 4px 8px;
                margin-top: 4px;
                overflow: hidden;
                font-size: 12px;
                color: #555;
                word-break: break-all;
                background-color: #E4E4E6;
                border-radius: 8px;
                & .ellipsis {
                    display: -webkit-inline-box;
                    text-overflow: ellipsis;
                    -webkit-line-clamp: 4;
                    -webkit-box-orient: vertical;
                }
            }
            & .pointer {
                cursor: pointer;
            }
        }
    }

    .message-item.left {
        text-align: left;
        & .message-avatar {
            float: left;
        }
        & .text, .message-reply {
            margin-right: auto;
        }
    } 

    .message-item.right {
        text-align: right;
        & .message-avatar {
            float: right;
        }
        & .text, .message-reply {
            margin-left: auto;
        }
    } 

    .message-item.left .message-content .text {
        color: #000000;
        background-color: #E4E4E6;
    }

    .message-item .message-content .text:before {
        position: absolute;
        left: -15px;
        top: 5px;
        width: 0;
        height: 0;
        border: 8px solid transparent;
        border-right-color: #1D90F5;
        content: "";
    }

    .message-item.left .message-content .text::before {
        border-right-color: #E4E4E6;
    }

    .message-item.right .message-content .text::before {
        left: auto;
        right: -15px;
        border: 8px solid transparent;
        border-left-color: #1D90F5;
    }

    .message-item.right .message-status {
        margin-right: -15px;
    }

    .message-status {
        display: none;
        vertical-align: middle;
        width: 30px;
        height: 30px;
        line-height: 30px;
        font-size: 14px;
        text-align: center;
        animation: loop 2s linear infinite;
        -webkit-animation: loop 2s linear infinite;
        margin-left: -15px;

    }

</style>